package com.gintama.redis.redisson;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Redisson则是基于Redis、Lua和Netty建立起了成熟的分布式解决方案
 */
public class RedissonLock {
    @Autowired
    private RedissonClient redissonClient;
    /**
     * redisson分布式锁
     * redisson实现可重入锁：新增了一个获取锁的次数。它舍弃了我们之前使用的Redis中String类型的setnx方法，改成用Hash类型的方法，
     * 分别存入锁的key，value存线程标识和锁的次数。
     * 当同一个中的方法获取到同一把锁后，锁的次数+1，在释放锁的时候，不仅判断线程标识是否是自己的，
     * 还要判断锁的次数，如果次数-1 为0，采取释放锁。 以此来实现可重入锁。
     *
     *
     */
    public void redissonLock() {
        RLock lock = redissonClient.getLock("order:" + 1);
        boolean isLock = lock.tryLock();
        if (!isLock) {
            return;
        }
        try {
            //业务逻辑
        }finally {
            lock.unlock();
        }
    }

    /**
     * Redisson分布式锁的主从一致性（MutiLock锁）
     * 解决：此时我们去写命令，写在主机上， 主机会将数据同步给从机，但是假设在主机还没有来得及把数据写入到从机去的时候，
     * 此时主机宕机，哨兵会发现主机宕机，并且选举一个slave变成master，而此时新的master中实际上并没有锁信息，
     * 此时锁信息就已经丢掉了
     *
     * 每个节点的地位都是一样的， 这把锁加锁的逻辑需要写入到每一个主丛节点上，只有所有的服务器都写入成功，
     * 此时才是加锁成功，假设现在某个节点挂了，那么他去获得锁的时候，只要有一个节点拿不到，都不能算是加锁成功，
     * 就保证了加锁的可靠性。
     */
}
